package com.example.nfcaccesssystem;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.util.Log;

public class Model implements IModel {

	
	final String ipAddress = "http://172.30.242.233:9000/";
	
	
	@Override
	public void getUsers() {
		
		GetUsersTask get = new GetUsersTask();
		get.execute(ipAddress + "getusers");
	}

	

	@Override
	public void createUser(String name, String accessId, Door[] doorArray) {
		CreateUserTask post = new CreateUserTask();
		JSONArray arr = new JSONArray();
		JSONObject jsonObject = new JSONObject();
		
		for (Door door : doorArray) {
			arr.put(door.getId());
		}
		
		try {
			jsonObject.put("doors", arr);
			jsonObject.put("name", name);
			jsonObject.put("accessid", accessId);
		} catch (JSONException e) {
			
			e.printStackTrace();
		}
		
		Log.i("CreateUser JSON", jsonObject.toString());
		post.execute(ipAddress + "createuser", jsonObject.toString());
	}
	
	@Override
	public void changeUserName(int id, String name) {
		ChangeUserNameTask post = new ChangeUserNameTask();
		
		post.execute(ipAddress + "changeusername", id + "", name);
		
	}



	@Override
	public void changeUserAccessId(int id, String accessId) {
		ChangeUserAccessIdTask post = new ChangeUserAccessIdTask();
		
		post.execute(ipAddress + "changeuseraccessid", id + "", accessId);
		
	}
	
	
	public void createDoor(String newDoorInfo, User[] userArray) {
		CreateDoorTask post = new CreateDoorTask();
		JSONArray arr = new JSONArray();
		
		JSONObject jsonObject = new JSONObject();
		
		for (User user : userArray) {
			arr.put(user.getId());
		}
		
		try {
			jsonObject.put("users", arr);
		
		
			jsonObject.put("info", newDoorInfo);
		} catch (JSONException e) {
			
			e.printStackTrace();
		}
		
		post.execute(ipAddress + "createdoor", jsonObject.toString());
	}

	@Override
	public void deleteDoor(int id) {
		
		PostDeleteDoorTask post = new PostDeleteDoorTask();
		post.execute(ipAddress + "deletedoor/" + id);
	}
	
	@Override
	public void deleteUser(int id) {
		PostDeleteUserTask post = new PostDeleteUserTask();
		post.execute(ipAddress + "deleteoneuser/" + id);
		
	}
	
	@Override
	public void getDoors(){
		
		GetDoorsTask get = new GetDoorsTask();
		get.execute(ipAddress + "getdoors");
	}

	@Override
	public void getUsersAndAccess(Door d) {
		
		GetUsersAndAccessTask get = new GetUsersAndAccessTask();
		get.execute(ipAddress + "getuseraccessbydoorid/" + d.getId());
	}

	@Override
	public void getDoorsAndAccess(User u) {
		GetDoorsAndAccessTask get = new GetDoorsAndAccessTask();
		get.execute(ipAddress + "getdooraccessbyuserid/" + u.getId());
		
	}
	
	@Override
	public void addUserDoorAccess(User u, Door d) {
		
		PostUserDoorAccessTask post = new PostUserDoorAccessTask();
		
		post.execute(ipAddress + "adduserdooraccess", u.getId() + "", d.getId() + "");
		
	}
	
	@Override
	public void changeDoorInfo(int id, String info) {
		
		ChangeDoorInfoTask post = new ChangeDoorInfoTask();
		
		post.execute(ipAddress + "changedoorinfo", id + "", info);
	}

	@Override
	public void removeUserDoorAccess(User u, Door d) {
		
		PostUserDoorAccessTask post = new PostUserDoorAccessTask();
		
		post.execute(ipAddress + "deleteuserdooraccess", u.getId() + "", d.getId() + "");	
		
	}
	
	public String genericAsyncHttpGetTask(String...params){
		final HttpClient httpclient = new DefaultHttpClient();
		String URL = null;
		String content = null;
		
		try {
			//URL passed to the AsyncTask 
            URL = params[0];
            
    		HttpGet httpget = new HttpGet(URL);
    		httpget.setHeader("Content-Type", "application/json");
    	    HttpResponse response = httpclient.execute(httpget);
    	    
    	    StatusLine statusLine = response.getStatusLine();
    	    if(statusLine.getStatusCode() == HttpStatus.SC_OK){
    	    	ByteArrayOutputStream out = new ByteArrayOutputStream();
    	        response.getEntity().writeTo(out);
    	        out.close();
    	        content = out.toString();
    	    }
    	    else {
    	    	response.getEntity().getContent().close();
    	    	throw new IOException(statusLine.getReasonPhrase());
    	    }
	        
    	    
		}
		catch(Exception e){
			
		}

		return content;
	}
	
	class GetDoorsTask extends AsyncTask<String, Void, String> {

		@Override
		protected String doInBackground(String... params) {
			
			String response = genericAsyncHttpGetTask(params);
			
			return response;
		}
		
		protected void onPostExecute(String response){    	
	    	  Controller.getInstance().setDoors(response);   	
		}
	}
	
	class GetUsersTask extends AsyncTask<String, Void, String> {
		
		@Override
		protected String doInBackground(String... params) {
			
			String response = genericAsyncHttpGetTask(params);
			
			return response;
		}
		
		protected void onPostExecute(String response){    	
	    	  Controller.getInstance().setUsers(response);   	
		}
	}
	
	class GetUsersAndAccessTask extends AsyncTask<String, Void, String> {

		@Override
		protected String doInBackground(String... params) {
			
			String response = genericAsyncHttpGetTask(params);
			
			return response;
		}
		
		protected void onPostExecute(String response){    	
	    	  Controller.getInstance().setUsersAndAccess(response);   	
		}
	}
	
	class GetDoorsAndAccessTask extends AsyncTask<String, Void, String> {

		@Override
		protected String doInBackground(String... params) {
			
			String response = genericAsyncHttpGetTask(params);
			
			return response;
		}
		
		protected void onPostExecute(String response){    	
	    	  Controller.getInstance().setDoorsAndAccess(response);   	
		}
	}
	
	class PostUserDoorAccessTask extends AsyncTask<String, Void, Boolean> {

		@Override
		protected Boolean doInBackground(String... params) {
			final HttpClient httpclient = new DefaultHttpClient();
			String URL = null;
			String userId = null;
			String doorId = null;
			
			try {
				URL = params[0];
				userId = params[1];
				doorId = params[2];
				
				HttpPost httppost = new HttpPost(URL);
				httppost.setHeader("Content-Type", "application/json");
				httppost.setHeader("Accept", "application/json");
				
				JSONObject JSON = new JSONObject();
				
				JSON.put("userid", userId);
				JSON.put("doorid", doorId);
				Log.i("Change Access Right", JSON.toString());
				StringEntity se = new StringEntity(JSON.toString());
				
				httppost.setEntity(se);  
				
			    HttpResponse response = httpclient.execute(httppost);
			    
			    StatusLine statusLine = response.getStatusLine();
			    if(statusLine.getStatusCode() != HttpStatus.SC_OK){
			    	return false;
			    }
				
			}
			catch (Exception e){
				
			}
			return true;
		}
		
		protected void onPostExecute(boolean response){    	
	    	 Controller.getInstance().setUsersDoorAccess(response);
		}
	}
	
	class ChangeDoorInfoTask extends AsyncTask<String, Void, Boolean> {

		@Override
		protected Boolean doInBackground(String... params) {
			final HttpClient httpclient = new DefaultHttpClient();
			String URL = null;
			String doorId = null;
			String doorInfo = null;
			
			try {
				URL = params[0];
				doorId = params[1];
				doorInfo = params[2];
				
				HttpPost httppost = new HttpPost(URL);
				httppost.setHeader("Content-Type", "application/json");
				httppost.setHeader("Accept", "application/json");
				
				JSONObject JSON = new JSONObject();
				
				JSON.put("doorid", doorId);
				JSON.put("doorinfo", doorInfo);
				
				StringEntity se = new StringEntity(JSON.toString());
				
				httppost.setEntity(se);  
				
			    HttpResponse response = httpclient.execute(httppost);
			    
			    StatusLine statusLine = response.getStatusLine();
			    if(statusLine.getStatusCode() != HttpStatus.SC_OK){
			    	return false;
			    }
				
			}
			catch (Exception e){
				
			}
			return true;
		}
		
		protected void onPostExecute(boolean response){    	
	    	 Controller.getInstance().setUsersDoorAccess(response);
		}
	}
	
	class ChangeUserNameTask extends AsyncTask<String, Void, Boolean> {

		@Override
		protected Boolean doInBackground(String... params) {
			final HttpClient httpclient = new DefaultHttpClient();
			String URL = null;
			String userId = null;
			String userName = null;
			
			try {
				URL = params[0];
				userId = params[1];
				userName = params[2];
				
				HttpPost httppost = new HttpPost(URL);
				httppost.setHeader("Content-Type", "application/json");
				httppost.setHeader("Accept", "application/json");
				
				JSONObject JSON = new JSONObject();
				
				JSON.put("userid", userId);
				JSON.put("username", userName);
				
				StringEntity se = new StringEntity(JSON.toString());
				
				httppost.setEntity(se);  
				
			    HttpResponse response = httpclient.execute(httppost);
			    
			    StatusLine statusLine = response.getStatusLine();
			    if(statusLine.getStatusCode() != HttpStatus.SC_OK){
			    	return false;
			    }
				
			}
			catch (Exception e){
				
			}
			return true;
		}
		
		protected void onPostExecute(boolean response){    	
	    	 Controller.getInstance().setDoorsUserAccess(response);
		}
	}
	
	class ChangeUserAccessIdTask extends AsyncTask<String, Void, Boolean> {

		@Override
		protected Boolean doInBackground(String... params) {
			final HttpClient httpclient = new DefaultHttpClient();
			String URL = null;
			String userId = null;
			String userAccessId = null;
			
			try {
				URL = params[0];
				userId = params[1];
				userAccessId = params[2];
				
				HttpPost httppost = new HttpPost(URL);
				httppost.setHeader("Content-Type", "application/json");
				httppost.setHeader("Accept", "application/json");
				
				JSONObject JSON = new JSONObject();
				
				JSON.put("userid", userId);
				JSON.put("useraccessid", userAccessId);
				
				StringEntity se = new StringEntity(JSON.toString());
				
				httppost.setEntity(se);  
				
			    HttpResponse response = httpclient.execute(httppost);
			    
			    StatusLine statusLine = response.getStatusLine();
			    if(statusLine.getStatusCode() != HttpStatus.SC_OK){
			    	return false;
			    }
				
			}
			catch (Exception e){
				
			}
			return true;
		}
		
		protected void onPostExecute(boolean response){    	
	    	 Controller.getInstance().setDoorsUserAccess(response);
		}
	}
	
	class CreateDoorTask extends AsyncTask<String, Void, Boolean> {

		@Override
		protected Boolean doInBackground(String... params) {
			final HttpClient httpclient = new DefaultHttpClient();
			String URL = null;
			String json = null;
			
			try {
				URL = params[0];
				json = params[1];
				
				HttpPost httppost = new HttpPost(URL);
				httppost.setHeader("Content-Type", "application/json");
				httppost.setHeader("Accept", "application/json");
				
				StringEntity se = new StringEntity(json);
				
				httppost.setEntity(se);
				
			    HttpResponse response = httpclient.execute(httppost);
			    
			    StatusLine statusLine = response.getStatusLine();
			    if(statusLine.getStatusCode() != HttpStatus.SC_OK){
			    	return false;
			    }
				
			}
			catch (Exception e){
				
			}
			return true;
		}
		
		@Override
		protected void onPostExecute(Boolean response){    	
	    	 Controller.getInstance().setNewDoor(response);
		}
	}
	
	class CreateUserTask extends AsyncTask<String, Void, Boolean> {

		@Override
		protected Boolean doInBackground(String... params) {
			final HttpClient httpclient = new DefaultHttpClient();
			String URL = null;
			String json = null;
			
			try {
				URL = params[0];
				json = params[1];
				
				HttpPost httppost = new HttpPost(URL);
				httppost.setHeader("Content-Type", "application/json");
				httppost.setHeader("Accept", "application/json");
				
				StringEntity se = new StringEntity(json);
				
				httppost.setEntity(se);
				
			    HttpResponse response = httpclient.execute(httppost);
			    
			    StatusLine statusLine = response.getStatusLine();
			    if(statusLine.getStatusCode() != HttpStatus.SC_OK){
			    	return false;
			    }
				
			}
			catch (Exception e){
				
			}
			return true;
		}
		
		@Override
		protected void onPostExecute(Boolean response){    	
	    	 Controller.getInstance().setNewUser(response);
		}
	}

	class PostDeleteDoorTask extends AsyncTask<String, Void, Boolean> {
		
		
		@Override
		protected Boolean doInBackground(String... params) {
			final HttpClient httpclient = new DefaultHttpClient();
			String URL = null;
			
			try {
				URL = params[0];
				
				HttpPost httppost = new HttpPost(URL);
				httppost.setHeader("Content-Type", "application/json");
				httppost.setHeader("Accept", "application/json");

				HttpResponse response = httpclient.execute(httppost);
			    
			    StatusLine statusLine = response.getStatusLine();
			    if(statusLine.getStatusCode() != HttpStatus.SC_OK){
			    	return false;
			    }
				
			}
			catch (Exception e){
				
			}
			return true;
		}
		
		@Override
		protected void onPostExecute(Boolean response){    	
	    	 Controller.getInstance().setDeleteNewDoor(response);
		}
	}

	class PostDeleteUserTask extends AsyncTask<String, Void, Boolean> {
		
		
		@Override
		protected Boolean doInBackground(String... params) {
			final HttpClient httpclient = new DefaultHttpClient();
			String URL = null;
			
			try {
				URL = params[0];
				
				HttpPost httppost = new HttpPost(URL);
				httppost.setHeader("Content-Type", "application/json");
				httppost.setHeader("Accept", "application/json");

				HttpResponse response = httpclient.execute(httppost);
			    
			    StatusLine statusLine = response.getStatusLine();
			    if(statusLine.getStatusCode() != HttpStatus.SC_OK){
			    	return false;
			    }
				
			}
			catch (Exception e){
				
			}
			return true;
		}
		
		@Override
		protected void onPostExecute(Boolean response){    	
	    	 Controller.getInstance().setDeleteNewUser(response);
		}
	}
}
